/*
PIC32MX795F512L 3.2" TFT LCD Demo Board
Copyright (C) 2012 Craig Dawson, Aaron Mohtar, Craig Peacock

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

#include <p32xxxx.h>
#include <plib.h>
#include "board.h"
#include "SSD1289.h"
#include "XPT2046.h"
#include "OV7670.h"
#include "lcdImage.h"
#include "HardwareProfile.h"

// The FSIO.h is the header file for Microchip's MDDFS Library.
// This project assumes you have the Microchip Application Libraries (MAL)
// installed on your local development machine in
// C:\Microchip Solutions v2012-04-03
// You can download MAL from from http://www.microchip.com/mal
#include "FSIO.h"

//#include "lcdText.h"
#include "lcdDraw.h"

#pragma config FPLLMUL  = MUL_20        // PLL Multiplier        (8MHz / 2 = 4MHz x 20 = 80MHz)
#pragma config UPLLIDIV = DIV_2         // USB PLL Input Divider (8MHz Clock)
#pragma config UPLLEN   = ON        	// USB PLL Enabled
#pragma config FPLLIDIV = DIV_2         // PLL Input Divider	 (8MHz Clock)
#pragma config FPLLODIV = DIV_1         // PLL Output Divider
#pragma config FPBDIV   = DIV_1         // Peripheral Clock divisor
#pragma config FWDTEN   = OFF           // Watchdog Timer
#pragma config WDTPS    = PS1           // Watchdog Timer Postscale
#pragma config FCKSM    = CSDCMD        // Clock Switching & Fail Safe Clock Monitor
#pragma config OSCIOFNC = OFF           // CLKO Enable
#pragma config POSCMOD  = HS            // Primary Oscillator
#pragma config IESO     = OFF           // Internal/External Switch-over
#pragma config FSOSCEN  = OFF           // Secondary Oscillator Enable (KLO was off)
#pragma config FNOSC    = PRIPLL        // Oscillator Selection
#pragma config CP       = OFF           // Code Protect
#pragma config BWP      = OFF           // Boot Flash Write Protect
#pragma config PWP      = OFF           // Program Flash Write Protect
#pragma config ICESEL   = ICS_PGx2      // ICE/ICD Comm Channel Select
#pragma config DEBUG    = ON            // Background Debugger Enable

void PhotoFrame_Demo(void);
void TouchScreen_Demo(void);
void Graphics_Demo(void);
void Camera_Demo(void);


int main(void)
{
    //ANSELBbits.ANSB5 = 0;
    TRISBbits.TRISB5 = 0;	// Make VBUSON an output
    LATBbits.LATB5 = 1;		// Turn VBUS off, until required

    INTEnableSystemMultiVectoredInt();  // Enable multivector interrupts

    pmpInit();      // Initialise the Parallel Master Port used to talk to the LCD
    lcdInit();      // Initialise the LCD module
    lcdBlInit(100); // Initialise the LCD backlight control and set brightness to 100%

    lcdFillScreen(BLACK);
    lcdWriteString("Screen Initialised", 2,2,WHITE, BLACK);
    delayMs(1000);

    // Initialise UART3 for debug (printf)
    consoleInit();  
    lcdWriteString("Serial interface initialised",2,12, WHITE, BLACK);
    printf("Serial interface initialised\r\n");
    delayMs(500);

    // Initialise the Touch screen
    touchScrInit(INT_ENABLED);
    lcdWriteString("Touch screen initialised",2,22,WHITE, BLACK);
    printf("Touch screen intialised\r\n");
    delayMs(1000);

    printf("Microchip PIC32MX795F512L SSD1289 3.2\" TFT LCD Demo Board\r\n");
    lcdWriteString("PIC32MX795F512L SSD1289 3.2\"\nTFT LCD Demo Board\n",2,32,WHITE, BLACK);
    delayMs(1000);

    delayMs(2000);
    
    //PhotoFrame_Demo();
    //TouchScreen_Demo();
    //Graphics_Demo();
    Camera_Demo();
   
    while(1);
}

void Camera_Demo(void)
{
    ov7670Init();
    do {
        ov7670DisplayFrame();
    } while(1);
}

void TouchScreen_Demo(void)
{

    unsigned int x;
    unsigned int y;

    lcdFillScreen(WHITE);
    delayMs(500);
    lcdWriteString("Touch screen demo (+ buttons)",2,2, BLACK, WHITE);

    do {
        if (touchScrGetCord(&x, &y)) {
            lcdSetPixel(x,y,BLACK); 
           //delayMs(1);
        }

        // display button labels
        lcdWriteString("RST",212,130, BLACK, WHITE);
        lcdWriteString("CAL",212,195, BLACK, WHITE);
        lcdWriteString("CLR",212,260, BLACK, WHITE);

        if(S1 == 0)
        {
            lcdFillScreen(WHITE);
            delayMs(1000);
        }
        if(S2 == 0)
        {
            touchScrCalibrate();
            lcdFillScreen(WHITE);
        }
        if(S3 == 0)// reset microcontroller
        {
            SYSKEY = 0xAA996655;
            SYSKEY = 0x556699AA;
            RSWRSTbits.SWRST = 1;
            x = RSWRST; // need to read the register to reset

        }
    } while (1);
}

void Graphics_Demo(void)
{

    do {

        printf("Filling screen with Red\r\n");
        lcdFillScreen(RED);
        delayMs(1000);

        printf("Filling screen with Green\r\n");
        lcdFillScreen(GREEN);
        delayMs(1000);

        printf("Filling screen with Blue\r\n");
        lcdFillScreen(BLUE);
        delayMs(1000);

        printf("Filling screen with White\r\n");
        lcdFillScreen(WHITE);
        delayMs(1000);

        printf("Filling screen with Yellow\r\n");
        lcdFillScreen(YELLOW);
        delayMs(1000);

        //-------------------------------------------------
        // this section just demnstrates various functions
        lcdWriteString("AM is just great!",50,50,BLACK, YELLOW);
        delayMs(1000);

        lcdDrawLine(10,10,100,200,RED);
        delayMs(1000);

        lcdWriteInt(523,50,70, 4, BLUE, YELLOW);

        unsigned int temperature = 25;
        lcdDisplayVariable("Temperature:", temperature, 2, "deg",20,100,RED,YELLOW);
        delayMs(1000);

        lcdDrawRectangle(49,48,185,59,RED,NOFILL);
        delayMs(1000);

        lcdDrawRectangle(100,220,150,300,GREEN,FILL);
        lcdDrawCircle(120, 160, 50, FILL, BLACK);
        delayMs(1000);

    } while (1);
}

void PhotoFrame_Demo(void)
{
    
#ifdef USE_USB_INTERFACE

    printf("Initalising USB Stack\r\n");
    USBInitialize(0);
    TMR3Init();

    while(!USBHostMSDSCSIMediaDetect());
#endif

#ifdef USE_SD_INTERFACE_WITH_SPI

    // Detect SDcard and initialise file system stack
    printf("Waiting for SDcard...\r\n");
    lcdWriteString("Waiting for SDcard...",2,62,WHITE, BLACK);
    while (!MDD_MediaDetect());
#endif

    // This photo frame demo loads three different .BMP images from
    // the SD card. They must be 320x240 images encoded in 16 bit
    // mode (R5 G6 B5). I use GIMP for this task.

    printf("Initialising FS Library . . .\r\n");
    while (!FSInit());

    do {

        lcdLoadBitmap("Scene01.bmp");
        delayMs(5000);

        lcdLoadBitmap("Scene02.bmp");
        delayMs(5000);

        lcdLoadBitmap("Scene03.bmp");
        delayMs(5000);

    } while(1);

}
